/**
 * *
 * @description Encapsulation a jQuery library
 * @Author Yeates Win
 * @version 0.1
 */
!function () {
	/**
	 *
	 @class jQuery
	 *
	 @constructor
	 *
	 @param {Select<Element>} selector
	 */
	var jQuery = function (selector) {
		// 创建并返回一个新的jQuery对象
		return new jQuery.prototype.init(selector);
	}
	// 重写jquery原型
	jQuery.fn = jQuery.prototype = {
		// 修正构造函数指向, 不修正则会指向Object
		constructor: jQuery,
		init: function (selector) {
			this.el = [];
			if (typeof selector === 'function') {
				setLoad(selector);
			} else if (typeof selector === 'string') {
				this.el = getElenent(selector);
			}
		},
		/**
		* *
		* @param Number num [索引]
		* @return Array
		*/
		eq: function (num) {
			if (typeof num === 'number') {
				this.el = [this.el[num]];
				return this;
			}
		},
		/**
		* *
		* @param Arrray ev [dom集合]
		* @param Function fun [回调函数]
		*/
		on: function (ev, fun) { // 设置事件绑定方法
			if (window.addEventListener) {
				for (var i = 0, len = this.el.length; i < len; i++) {
					this.el[i].addEventListener(ev, fun, false);
				}
			} else if (window.attachEvent) {
				for (var i = 0, len = this.el.length; i < len; i++) {
					this.el[i].attachEvent('on' + ev, function () {
						fun();
					});
				}
			}
		},
		/**
		* 实现text()方法
		* @param String str [文本内容]
		*/
		text: function (str) {
			var el = this.el;
			for (var i = 0, len = el.length; i < len; i++) {
				el[i].innerText = str
			}
		},
		/**
		* 实现html()方法
		* @param String str [文本内容]
		*/
		html: function (str) { // 设置html() 方法
			var el = this.el;
			for (var i = 0, len = el.length; i < len; i++) {
				el[i].innerHTML = str
			}
		},
		/**
		* 实现click()方法
		* @param Function fun [回调函数]
		*/
		click: function (fun) {
			if (typeof fun !== 'function') {
				console.error(fun + ' is not a function');
				return;
			}
			if (window.addEventListener) {
				for (var i = 0, len = this.el.length; i < len; i++) {
					this.el[i].addEventListener('click', fun, false);
				}
			} else if (window.attachEvent) {
				for (var i = 0, len = this.el.length; i < len; i++) {
					this.el[i].attachEvent('onclick', function () {
						fun();
					});
				}
			}
		},
		/**
		* 实现attr()方法
		* @param String at [属性]
		* @param String value [想要设置的属性内容]
		* @return Array/String
		*/
		attr: function (at, value) {
			var el = this.el;
			var arr = [];
			if (value) {
				for (var i = 0, len = el.length; i< len; i++) {
					this.el[i].setAttribute(at, value)
				}
			}
			if (el.length > 1) {
				for (var i = 0, len = el.length; i< len; i++) {
					arr.push(this.el[i].getAttribute(at))
				}
				return arr;
			} else {
				return this.el[0].getAttribute(at)
			}
		},
		/**
		* 实现val()方法
		* @param String str [文本内容]
		* @return String
		*/
		val: function (str) {
			var el = this.el;
			var arr = [];
			if (str) {
				for (var i = 0, len = el.length; i< len; i++) {
					this.el[i].value = str;
				}
			} else {
				if (el.length > 1) {
					for (var i = 0, len = el.length; i< len; i++) {
						arr.push(this.el[i].value);
					}
					return arr;
				} else {
					return this.el[0].value;
				}
			}
		},
		/**
		* 实现text()方法
		* @param String par [设置速度，有三个可设置的值(slow、 fast、 normal,默认为normal)]
		* @param Number par [设置具体速度，单位为毫秒]
		*/
		show: function (par) { // 设置show()方法
			var el = this.el;
			var that = this;
			var n = 0;
			if (!par || typeof par == 'string') {
				var full;
				var speed = 100;
				if (par == 'slow') {
					speed = 150;
				}else if (par == 'fast') {
					speed = 70;
				}
				var timer = setInterval(function () {
					n++;
					if (n >= 10) {
						clearInterval(timer);
						full = 1;
					}
					for (var i = 0, len = el.length; i< len; i++) {
						that.el[i].style.display = 'block';
						if (full) {
							that.el[i].style.opacity = full;
						} else {
							that.el[i].style.opacity = '0.' + n;
						}

					}
				}, speed);
			} else if (typeof par == 'number') {
				var full;
				var speed = par;
				var timer = setInterval(function () {
					n++;
					if (n >= 10) {
						clearInterval(timer);
						full = 1;
					}
					for (var i = 0, len = el.length; i< len; i++) {
						that.el[i].style.display = 'block';
						if (full) {
							that.el[i].style.opacity = full;
						} else {
							that.el[i].style.opacity = '0.' + n;
						}
					}
				}, speed);
			}
		},
		/**
		* 实现text()方法
		* @param String par [设置速度，有三个可设置的值(slow、 fast、 normal,默认为normal)]
		* @param Number par [设置具体速度，单位为毫秒]
		*/
		hide: function (arg) { // 实现hide方法
			var el = this.el;
			var that = this;
			var n = 9;
			if (!arg || typeof arg == 'string') {
				var speed = 100;
				if (arg == 'fast') {
					speed = 70;
				} else if (arg == 'slow') {
					speed = 150;
				}
				var timer = setInterval(function () {
					n--;
					if (n <= 0) {
						clearInterval(timer);
						for (var i = 0, len = el.length; i < len; i++) {
							that.el[i].style.display = 'none';
						}
					}
					for (var i = 0, len = el.length; i < len; i++) {
						that.el[i].style.opacity = '0.' + n;
					}
				}, speed);
			} else if (typeof arg == 'number') {
				var timer = setInterval(function () {
					n--;
					if (n <= 0) {
						clearInterval(timer);
						for (var i = 0, len = el.length; i < len; i++) {
							that.el[i].style.display = 'none';
						}
					}
					for (var i = 0, len = el.length; i < len; i++) {
						that.el[i].style.opacity = '0.' + n;
					}
				}, arg);
			}
		}
	};
	/**
	* 实现$.ajax()方法
	* @param Object obj [设置ajax请求参数以及请求成功后的回调]
	*/
	jQuery.ajax = jQuery.fn.ajax = function (obj) {
		// 初始化参数,有新参数则覆盖,没有就采用默认值
		var xmlhttp, type, url, async, dataType, data;
	    if (typeof(obj) != 'object')  return false;
	    type = obj.type == undefined ? 'POST' : obj.type.toUpperCase();
	    url = obj.url == undefined ? window.location.href : obj.url;
	    async = obj.async == undefined ? true : obj.type;
	    dataType = obj.dataType == undefined ? 'HTML' : obj.dataType.toUpperCase();
	    data = obj.data == undefined ? {} : obj.data;

	    // 转换ajax data参数
	    var formatParams = function () { 
	        if (typeof(data) == "object") {
	            var str = "";
	            for (var pro in data) {
	                str += pro + "=" + data[pro] + "&";
	            }
	            data = str.substr(0, str.length - 1);
	        }
	        if (type == 'GET' || dataType == 'JSONP') {
	            if (url.lastIndexOf('?') == -1) {
	                url += '?' + data;
	            } else {
	                url += '&' + data;
	            }
	        }
	    }

	    // 创建httpRequest对象
	    if (window.XMLHttpRequest) {
	        xmlhttp = new XMLHttpRequest();
	    } else {
	        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	    }

	    // 设置请求方式
	    if (dataType == 'JSONP') { 
	    	// 跨域(jsonp)  通过动态创建script标签原理实现跨域
	        if (typeof(obj.beforeSend) == 'function')obj.beforeSend(xmlhttp);
	        var callbackName = ('jsonp_' + Math.random()).replace(".", "");
	        var oHead = document.getElementsByTagName('head')[0];
	        data.callback = callbackName;
	        var ele = document.createElement('script');
	        ele.type = "text/javascript";
	        ele.onerror = function () {
	            console.log('请求失败');
	            obj.error && obj.error("请求失败");
	        };
	        oHead.appendChild(ele);
	        window[callbackName] = function (json) {
	            oHead.removeChild(ele);
	            window[callbackName] = null;
	            obj.success && obj.success(json);
	        };
	        formatParams();
	        ele.src = url;
	        return;
	    } else { 
	    	// 非跨域
	        formatParams();
	        xmlhttp.open(type, url, async);
	        xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
	        if (typeof(obj.beforeSend) == 'function') obj.beforeSend(xmlhttp);
	        xmlhttp.send(data);
	        xmlhttp.onreadystatechange = function () {
	            if (xmlhttp.status != 200) {
	                console.log(xmlhttp.status + '错误');
	                obj.error && obj.error(xmlhttp.status + '错误');
	                return;
	            }
	            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
	                if (dataType == 'JSON') {
	                    try {
	                        res = JSON.parse(xmlhttp.responseText);
	                    } catch (e) {
	                        console.log('返回的json格式不正确');
	                        obj.error('返回的json格式不正确');
	                    }
	                } else if (dataType == 'XML') {
	                    res = xmlhttp.responseXML;
	                } else {
	                    res = xmlhttp.responseText;
	                }
	                obj.success && obj.success(res);
	            }
	        }
	    }
	}
	// 实现$.extend方法
	jQuery.extend = jQuery.fn.extend = function (obj1, obj2) {
		var obj = {};
		for (var attr in obj1) {
			obj[attr] = obj1[attr];
		}
		for (var attr in obj2) {
			obj[attr] = obj2[attr];
		}
		return obj;
	}
	// 实现$.trim方法
	jQuery.trim = jQuery.fn.trim = function (str) {
		var obj = str
		if (typeof obj == 'string') {
			var reg = /\s+/g;
			obj = obj.replace(reg, '');
		} else {
			console.error(obj + ' is not a string');
		}
		return obj;
	}

	// 修改初始化方法的原型，另其指向jquery
	jQuery.prototype.init.prototype = jQuery.prototype;
	// 设置$与jquery等价并对外公开
	window.jQuery = window.$ = jQuery;

	/**
	* 实现设置页面加载事件
	* @param Function fun [页面加载后的回调函数]
	*/
	function setLoad (fun) {
		if (window.addEventListener) {
			window.addEventListener('load', fun, false); // w3c标准, firefox、chrome...
		} else if (window.attachEvent) {
			window.attachEvent('onload', function () { // 兼容ie浏览器
				fun();
			});
		}
	}
	/**
	* 获取dom节点
	* @param String arg [可直接传入css选择器]
	*/
	function getElenent (arg) {
		var arr = [];
		var obj = document.querySelectorAll(arg);
		for (var i = 0, len = obj.length; i < len; i++) {
			arr.push(obj[i]);
		}
		return arr;
	}
}();